package whr.modules.sys.controller;

import cn.hutool.poi.excel.ExcelReader;
import cn.hutool.poi.excel.ExcelUtil;
import cn.hutool.poi.excel.ExcelWriter;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.util.HtmlUtils;
import whr.common.annotation.SysLog;
import whr.common.utils.DateUtils;
import whr.common.utils.PageUtils;
import whr.common.utils.R;
import whr.common.utils.ResponseApi;
import whr.common.validator.ValidatorUtils;
import whr.common.validator.group.AddGroup;
import whr.modules.sys.entity.SysOrganizations;
import whr.modules.sys.service.SysOrganizationsService;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;


@RestController
@RequestMapping("/sys/organizations")
@Slf4j
public class SysOrganizationsController extends AbstractController {

    @Autowired
    private SysOrganizationsService sysOrganizationsService;

    /**
     * 列表
     */
    @RequestMapping(value = "/list", method = RequestMethod.GET)
//    @RequiresPermissions("sys:organizations:list")
    public R list(@RequestParam Map<String, Object> params) {
        PageUtils page = sysOrganizationsService.queryPage(params);
        return R.ok().put("page", page);
    }

    //根据组织机构名称模糊查询
    @RequestMapping(value = "/findByLikeName", method = RequestMethod.GET)
    public ResponseApi findByName(@RequestParam("name") String name) {
        log.info("name{}", name);
        List<SysOrganizations> sysOrganizations = sysOrganizationsService.selectByLikeName(name);
        return ResponseApi.success(sysOrganizations);
    }


    @GetMapping("/info")
    public R info(@RequestParam("id") Integer id) {
        return R.ok().put("sysOrganizations", sysOrganizationsService.getById(id));
    }

    /**
     * 保存
     */
    @SysLog("保存部门")
    @RequestMapping(value = "/save", method = RequestMethod.POST)
    @RequiresPermissions("sys:organizations:save")
    public ResponseApi save(@RequestBody SysOrganizations sysOrganizations) {
        //数据校验
        ValidatorUtils.validateEntity(sysOrganizations, AddGroup.class);
        //根据部门的name判断添加的部门是否存在，若存在这给出提示
        //如果不存在，则保存
        if (!sysOrganizationsService.getByName(sysOrganizations.getName())) {
            sysOrganizations.setUpdateUserId(Integer.valueOf(String.valueOf(getUserId())));
            //设置创建者为当前登录的用户
            sysOrganizations.setCreateUserId(Integer.valueOf(String.valueOf(getUserId())));
            //保存
            boolean save = sysOrganizationsService.saveBySysOrganizations(sysOrganizations);
            if (save) {
                return ResponseApi.success("保存成功！");
            } else {
                return ResponseApi.failed("保存失败！");
            }
        } else {
            //否则提示错误
            return ResponseApi.failed( "保存失败!部门:("+sysOrganizations.getName()+")已存在!");

        }
    }

    /**
     * 修改
     */
    @SysLog("修改部门")
    @RequestMapping(value = "/update", method = RequestMethod.POST)
    @RequiresPermissions("sys:organizations:update")
    public ResponseApi update(@RequestBody SysOrganizations sysOrganizations) {
            try {
                // 如果更新后的名字是已经存在的
                if (sysOrganizationsService.getByName(sysOrganizations.getName())) {
                    return ResponseApi.failed("更新失败! 部门:(" + sysOrganizations.getName() + ")已存在!");
                } else {
                    // 设置更新时间和更新者
                    sysOrganizations.setUpdateTime(DateUtils.now());
                    sysOrganizations.setUpdateUserId(Integer.valueOf(String.valueOf(getUserId())));
                    // 更新部门信息
                    sysOrganizationsService.updateById(sysOrganizations);
                    return ResponseApi.success("更新成功！");
                }
            } catch (Exception e) {
                // 异常处理
                log.error("更新部门失败: {}", e.getMessage(), e);
                return ResponseApi.failed("更新失败，请稍后重试！");
            }
    }

    /**
     * 真删除
     */
    @SysLog("删除部门")
    @PostMapping("/delete")
    @RequiresPermissions("sys:organizations:delete")
    public ResponseApi deleteZsc(@RequestBody Integer[] ids) {
        log.info("ids{}", ids);
        sysOrganizationsService.deleteBatch(ids);
        return ResponseApi.success();
    }


    /**
     * 批量导出excel文件
     * @param name
     */
    @GetMapping("/export")
    public void exportData(@RequestParam(required = false) String name,  // 部门名称
                           @RequestParam(required = false) String ids,  // 勾选的部门id
                           HttpServletResponse response   // 响应对象
    ) throws IOException {
        // 对输入进行基本的验证和清理，目的是为了防止XSS攻击
        if (name != null) {
            name = HtmlUtils.htmlEscape(name);  // 转义HTML字符
        }
        if (ids != null) {
            ids = HtmlUtils.htmlEscape(ids);   // 转义HTML字符
        }
        ExcelWriter writer = ExcelUtil.getWriter(true);   // 创建一个ExcelWriter对象
        List<SysOrganizations> list = new ArrayList<>();    // 创建一个集合

        LambdaQueryWrapper<SysOrganizations> wrapper = new LambdaQueryWrapper<>();
        if (StringUtils.isNotBlank(ids)) {
            String[] id = ids.split(",");
            List<Integer> orgId = Arrays.stream(id).map(Integer::valueOf).collect(Collectors.toList());
            wrapper.in(SysOrganizations::getId, orgId);   // 添加查询条件
        } else {
            wrapper.like(StringUtils.isNotBlank(name), SysOrganizations::getName, name);   // 添加查询条件
        }
        list = sysOrganizationsService.list(wrapper);
        writer.write(list, true);   // 写入数据到Excel

        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8");  // 设置响应头
        response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode("部门信息表", "UTF-8") + ".xlsx");  // 设置响应头
        ServletOutputStream outputStream = response.getOutputStream();  // 获取输出流
        writer.flush(outputStream, true);  // 刷新输出流
        writer.close();  // 关闭输出流
    }


    /**
     * 导入Excel文件
     * @param file
     * @return
     * @throws IOException
     */
    @PostMapping("/import")
    public ResponseApi importData(MultipartFile file) throws IOException {
        ExcelReader reader = ExcelUtil.getReader(file.getInputStream()); //读取Excel文件
        List<SysOrganizations> sysOrganizationsList = reader.readAll(SysOrganizations.class);//读取所有的数据
        System.out.println("sysorg"+sysOrganizationsList);

        //便利数据,判断部门是否已存在
        for (SysOrganizations org : sysOrganizationsList) {
            if(sysOrganizationsService.getByName(org.getName())){
                return ResponseApi.failed("数据批量导入错误!部门:("+org.getName()+")已存在");
            }
        }
       try{
           sysOrganizationsService.saveBatch(sysOrganizationsList);  //写入数据到数据库
       }catch (Exception e){
           e.printStackTrace();
           return ResponseApi.failed("数据批量导入错误");
       }
        return ResponseApi.success();
    }
}
